<?php
/**工期计算
 * 2009 05 28
 */
class CalculateDuration {
    var $aWeek = array(); 
    //var $aSpecialDay = array(array());
    var $dAMStartHour    = 9;  
    var $dAMStartMinute  = 0;
    var $dAMFinishHour   = 12; 
    var $dAMFinishMinute = 0;
    var $dPMStartHour    = 13; 
    var $dPMStartMinute  = 0;
    var $dPMFinishHour   = 18; 
    var $dPMFinishMinute = 0;
    var $dDayWorkTime    = 8;  

//
function CalculateDuration() {
    global $DB,$TABLE_PROJECT,$SEC,$_SESSION; 

    $sUserID = $SEC->sUserID;
    $iProjectID = $_SESSION["task_project_id"];

    $sWorkDay      = "0111110";
    $tAMStartTime  = "09:00";
    $tAMFinishTime = "12:00";
    $tPMStartTime  = "13:00";
    $tPMFinishTime = "18:00";
    $iDayWorkTime  = "8";

    if (isset($_SESSION["prj_dayWorkTime"]) && $_SESSION["prj_dayWorkTime"]!="") {
        $tAMStartTime  = $_SESSION["prj_amStartTime"];
        $tAMFinishTime = $_SESSION["prj_amFinishTime"];
        $tPMStartTime  = $_SESSION["prj_pmStartTime"];
        $tPMFinishTime = $_SESSION["prj_pmFinishTime"];
        $sWorkDay      = $_SESSION["prj_workDay"];
        $iDayWorkTime  = $_SESSION["prj_dayWorkTime"];
    } else {
        ////add dayWorkTime field in project management
        $sql  = "SELECT WORKDAY,AMSTARTTIME,AMENDTIME,PMSTARTTIME,PMENDTIME,DAYWORKTIME "; 
        $sql .= "FROM $TABLE_PROJECT ";
        $sql .= "WHERE ID='".$iProjectID."'";
        $rs = $DB->query($sql);
        if ($row = mysql_fetch_array($rs)) {
            $tAMStartTime  = $row["AMSTARTTIME"];
            $tAMFinishTime = $row["AMENDTIME"];
            $tPMStartTime  = $row["PMSTARTTIME"];
            $tPMFinishTime = $row["PMENDTIME"];
            $sWorkDay      = $row["WORKDAY"];
            $iDayWorkTime  = $row["DAYWORKTIME"];

            $_SESSION["prj_amStartTime"] = $tAMStartTime;
            $_SESSION["prj_amFinishTime"]= $tAMFinishTime;
            $_SESSION["prj_pmStartTime"] = $tPMStartTime;
            $_SESSION["prj_pmFinishTime"]= $tPMFinishTime;
            $_SESSION["prj_workDay"]     = $sWorkDay;
            $_SESSION["prj_dayWorkTime"] = $iDayWorkTime;
        }
    }
    $this->aWeek = fn_str_split($sWorkDay);
    $this->dAMStartHour    = date("G",strtoTime($tAMStartTime)); 
    $this->dAMStartMinute  = date("i",strtoTime($tAMStartTime));
    $this->dAMFinishHour   = date("G",strtoTime($tAMFinishTime));
    $this->dAMFinishMinute = date("i",strtoTime($tAMFinishTime));
    $this->dPMStartHour    = date("G",strtoTime($tPMStartTime)); 
    $this->dPMStartMinute  = date("i",strtoTime($tPMStartTime));
    $this->dPMFinishHour   = date("G",strtoTime($tPMFinishTime));
    $this->dPMFinishMinute = date("i",strtoTime($tPMFinishTime));
    $this->dDayWorkTime    = $iDayWorkTime;

}

//
function isWorkDay($now) {
    return $this->aWeek[date("w",$now)];
}
//
function calcMinute($dStart,$dEnd) {
    $tMinute=0;
    
    for ($i=1; $dStart<$dEnd; $i++) {
        $da = getdate($dStart);

        if (($da["hours"]>$this->dAMStartHour  || $da["hours"]==$this->dAMStartHour  && $da["minutes"]>=$this->dAMStartMinute) && 
            ($da["hours"]<$this->dAMFinishHour || $da["hours"]==$this->dAMFinishHour && $da["minutes"]<=$this->dAMFinishMinute)) $tMinute++;

        if (($da["hours"]>$this->dPMStartHour  || $da["hours"]==$this->dPMStartHour  && $da["minutes"]>=$this->dPMStartMinute) && 
            ($da["hours"]<$this->dPMFinishHour || $da["hours"]==$this->dPMFinishHour && $da["minutes"]<=$this->dPMFinishMinute)) $tMinute++;

        $dStart = strtotime("+1 minute",$dStart);
    }
    return $tMinute;
}

function calcDuration($startDate,$finishDate) {
    if ($startDate =="0000-00-00 00:00:00" || $startDate =="0000-00-00" || $startDate =="") return 0;
    if ($finishDate=="0000-00-00 00:00:00" || $finishDate=="0000-00-00" || $finishDate=="") return 0;
    $dStartDate = $startDate;
    $dFinishDate= $finishDate;
    $d1 = strtotime($dStartDate);
    $d2 = strtotime($dFinishDate);
    $da1= getdate($d1);
    $da2= getdate($d2);
    
    $dd = 0; 
    $tt = 0; 
    $i=0;$d=0;$dTemp=0;

    if ($da1["hours"]==0 && $da1["minutes"]==0) {
        $dStartDate = $dStartDate." ".$this->dAMStartHour.":".$this->dAMStartMinute;
        $d1 = strtotime($dStartDate);
        $da1= getdate($d1);
    }
    if ($da2["hours"]==0 && $da2["minutes"]==0) {
        $dFinishDate = $dFinishDate." ".$this->dPMFinishHour.":".$this->dPMFinishMinute;
        $d2 = strtotime($dFinishDate);
        $da2= getdate($d2);
    }
    
    if ($da1["hours"]>$this->dPMFinishHour || $da1["hours"]==$this->dPMFinishHour && $da1["minutes"]>$this->dPMFinishMinute) { 
        $d1 = strtotime("+1 day",$d1);
        $dStartDate = date("Y-m-d",$d1)." ".$this->dAMStartHour.":".$this->dAMStartMinute;
        $d1 = strtotime($dStartDate);
    }
    for ($i=0; $this->isWorkDay($d1)==0; $i++) { 
        $d1 = strtotime("+1 day",$d1);
        $dStartDate = date("Y-m-d",$d1)." ".$this->dAMStartHour.":".$this->dAMStartMinute;
        $d1 = strtotime($dStartDate);
    }

    if ($da2["hours"]<$this->dAMStartHour || $da2["hours"]==$this->dAMStartHour && $da2["minutes"]<$this->dAMStartMinute) { //ĵǰһ°ʱ
        $d2 = strtotime("-1 day",$d2);
        $dFinishDate = date("Y-m-d",$d2)." ".$this->dPMFinishHour.":".$this->dPMFinishMinute;
        $d2 = strtotime($dFinishDate);
    }
    for ($i=0; $this->isWorkDay($d2)==0; $i++) { 
        $d2 = strtotime("-1 day",$d2);
        $dFinishDate = date("Y-m-d",$d2)." ".$this->dPMFinishHour.":".$this->dPMFinishMinute;
        $d2 = strtotime($dFinishDate);
    }
    
    $d = ($d2 - $d1)/(60*60*24);
    if ($d>0 && $d<=1 && $this->isWorkDay($d2)==1) { 
        $tt = $this->calcMinute($d1,$d2);
    } else if ($d>1) { 
        $dTemp = strtotime(date("Y-m-d",$d1)." ".$this->dPMFinishHour.":".$this->dPMFinishMinute);
        $tt = $this->calcMinute($d1,$dTemp);
        $dTemp = strtotime(date("Y-m-d",$d2)." ".$this->dAMStartHour.":".$this->dAMStartMinute);
        $tt += $this->calcMinute($dTemp,$d2);
        
        $d1 = strtotime("+1 day",$d1);
        $dStartDate = date("Y-m-d",$d1)." ".$this->dAMStartHour.":".$this->dAMStartMinute;
        $d1 = strtotime($dStartDate);
        $d2 = strtotime("-1 day",$d2);
        $dFinishDate = date("Y-m-d",$d2)." ".$this->dPMFinishHour.":".$this->dPMFinishMinute;
        $d2 = strtotime($dFinishDate);
        
        for ($i=1; $d1 < $d2; $i++) {
            if ($this->isWorkDay($d1)==1) $dd++;
            $d1 = strtotime("+1 day",$d1); 
        }
    }
    if ($this->dDayWorkTime <= 0) {
        $tt = $tt/(60*8);
    } else {
        $tt = $tt/(60*$this->dDayWorkTime);
    }
    return round(($dd + $tt),2);
}//end of function

}//end of class

/**
 * auto calculate and adjust the datetime and present of precis
 */
function autoAdjustPrecis($parentID,$conn) {
    global $DB,$TABLE_TASK;

    $sql = "SELECT PARENTID,PLANSTARTDATE,PLANFINISHDATE,FINISHPERCENT,";
    $sql.= "FACTSTARTDATE,FACTFINISHDATE ";
    $sql.= "FROM $TABLE_TASK WHERE ID='".$parentID."'";
    $stmt = $DB->query($sql);
    if ($row = $DB->fetchArray($stmt)) {
        $sParentID       = $row["PARENTID"];
        $sPlanStartDate  = $row["PLANSTARTDATE"];
        $sPlanFinishDate = $row["PLANFINISHDATE"];
        $sFactStartDate  = $row["FACTSTARTDATE"];
        $sFactFinishDate = $row["FACTFINISHDATE"];
        $sFinishPercent  = $row["FINISHPERCENT"];
        $DB->freeResult($stmt);
    } else {
        return true;
    }
    
    $sql = "SELECT MIN(PLANSTARTDATE) AS PLANSTARTDATE,";
    $sql.= "MAX(PLANFINISHDATE) AS PLANFINISHDATE,";
    $sql.= "MIN(FACTSTARTDATE) AS FACTSTARTDATE,";
    $sql.= "MAX(FACTFINISHDATE) AS FACTFINISHDATE,";
    $sql.= "AVG(FINISHPERCENT) AS FINISHPERCENT ";
    $sql.= "FROM $TABLE_TASK WHERE PARENTID='".$parentID."'";
    $stmt = $DB->query($sql);
    if ($row = $DB->fetchArray($stmt)) {
        $sPlanStartDate2  = $row["PLANSTARTDATE"];
        $sPlanFinishDate2 = $row["PLANFINISHDATE"];
        $sFactStartDate2  = $row["FACTSTARTDATE"];
        $sFactFinishDate2 = $row["FACTFINISHDATE"];
        $sFinishPercent2  = round($row["FINISHPERCENT"],2);
    }
    $DB->freeResult($stmt);

    $sqlUpdate = "UPDATE $TABLE_TASK SET ";
    if ($sPlanStartDate != $sPlanStartDate2 || $sPlanFinishDate != $sPlanFinishDate2) {
        $sqlUpdate .= "PLANSTARTDATE='".$sPlanStartDate2."',";
        $sqlUpdate .= "PLANFINISHDATE='".$sPlanFinishDate2."',";
        $calcDur = new CalculateDuration();
        $sDur = $calcDur->calcDuration($sPlanStartDate2,$sPlanFinishDate2);
        $sqlUpdate .= "DURATION='".$sDur ."',";
    }
    if ($sFactStartDate != $sFactStartDate2 || $sFactFinishDate != $sFactFinishDate2) {
        $sqlUpdate .= "FACTSTARTDATE='".$sFactStartDate2."',";
        $sqlUpdate .= "FACTFINISHDATE='".$sFactFinishDate2."',";
    }
    $sqlUpdate .= "FINISHPERCENT='".$sFinishPercent2."' ";
    $sqlUpdate .= "WHERE ID='".$parentID."'";
    $DB->tquery($sqlUpdate,$conn);

    if ($sParentID == 0 || ($sPercent==$sFinishPercent
        && $sStartDate == $sPlanStartDate 
        && $sFinishDate== $sPlanFinishDate)) {
        return true;
    } else {
        autoAdjustPrecis($sParentID,$conn);
    }
}

?>